/**
 * 事件模型
 * 用于跨项目数据同步和事件通知
 */
const BaseModel = require('../config/models_config').base_model;

class EventModel extends BaseModel {
  constructor() {
    super();
    
    // 设置数据集合
    this._db = wx.cloud.database();
    this._collection = this._db.collection('cross_events');
    
    // 事件状态常量
    this.STATUS = {
      PENDING: 0,   // 待处理
      PROCESSING: 1, // 处理中
      DONE: 2,      // 已完成
      FAILED: 3      // 处理失败
    };
  }
  
  /**
   * 添加新事件
   * @param {Object} eventData 事件数据
   * @returns {Promise<String>} 事件ID
   */
  async addEvent(eventData) {
    // 事件数据基本结构
    const data = {
      // 事件来源项目标识
      sourceProject: eventData.sourceProject,
      
      // 事件类型
      type: eventData.type,
      
      // 事件数据
      data: eventData.data || {},
      
      // 目标项目列表
      targetProjects: eventData.targetProjects || [],
      
      // 事件状态：0-待处理, 1-处理中, 2-已完成, 3-处理失败
      status: this.STATUS.PENDING,
      
      // 处理结果
      results: {},
      
      // 重试次数
      retryCount: 0,
      
      // 最大重试次数
      maxRetries: eventData.maxRetries || 3,
      
      // 创建时间
      createTime: this._getTime(),
      
      // 更新时间
      updateTime: this._getTime()
    };
    
    // 插入数据库
    const result = await this._collection.add({
      data
    });
    
    return result._id;
  }
  
  /**
   * 获取待处理事件列表
   * @param {Object} options 查询选项
   * @returns {Promise<Array>} 事件列表
   */
  async getPendingEvents(options = {}) {
    const { limit = 10 } = options;
    
    const query = this._collection.where({
      status: this.STATUS.PENDING,
      retryCount: this._lt(3)
    });
    
    const list = await query.limit(limit).get();
    
    return list.data;
  }
  
  /**
   * 更新事件状态
   * @param {String} eventId 事件ID
   * @param {Number} status 新状态
   * @param {Object} results 处理结果
   * @returns {Promise<Boolean>} 成功标志
   */
  async updateEventStatus(eventId, status, results = {}) {
    if (!eventId) return false;
    
    const data = {
      status,
      updateTime: this._getTime()
    };
    
    // 添加处理结果
    if (Object.keys(results).length > 0) {
      data.results = results;
    }
    
    try {
      await this._collection.doc(eventId).update({
        data
      });
      return true;
    } catch (err) {
      console.error('[EventModel] 更新事件状态失败:', err);
      return false;
    }
  }
  
  /**
   * 增加事件重试次数
   * @param {String} eventId 事件ID
   * @returns {Promise<Boolean>} 成功标志
   */
  async incrementRetry(eventId) {
    if (!eventId) return false;
    
    try {
      await this._collection.doc(eventId).update({
        data: {
          retryCount: this._inc(1),
          updateTime: this._getTime()
        }
      });
      return true;
    } catch (err) {
      console.error('[EventModel] 增加重试次数失败:', err);
      return false;
    }
  }
  
  /**
   * 获取事件详情
   * @param {String} eventId 事件ID
   * @returns {Promise<Object>} 事件详情
   */
  async getEventById(eventId) {
    if (!eventId) return null;
    
    try {
      const res = await this._collection.doc(eventId).get();
      return res.data;
    } catch (err) {
      console.error('[EventModel] 获取事件详情失败:', err);
      return null;
    }
  }
  
  /**
   * 获取指定项目相关事件
   * @param {String} projectId 项目标识
   * @param {Object} options 查询选项
   * @returns {Promise<Array>} 事件列表
   */
  async getProjectEvents(projectId, options = {}) {
    if (!projectId) return [];
    
    const { page = 1, size = 20, status } = options;
    const where = {
      $or: [
        { sourceProject: projectId },
        { targetProjects: projectId }
      ]
    };
    
    // 添加状态过滤
    if (status !== undefined) {
      where.status = status;
    }
    
    try {
      const query = this._collection.where(where);
      const list = await query
        .skip((page - 1) * size)
        .limit(size)
        .orderBy('createTime', 'desc')
        .get();
      
      const total = await this._collection.where(where).count();
      
      return {
        list: list.data,
        total: total.total
      };
    } catch (err) {
      console.error('[EventModel] 获取项目事件列表失败:', err);
      return { list: [], total: 0 };
    }
  }
}

module.exports = EventModel; 